package br.com.iswe.core.web.util;

import java.util.HashMap;
import java.util.Map;

import javax.persistence.Transient;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;

import br.com.iswe.core.exp.ISWEConfigurationException;
import br.com.iswe.core.facade.FacadeContract;

@SuppressWarnings("unchecked")
public abstract class BasicServiceLocator implements ServiceLocator, BeanFactoryAware{

	private BeanFactory beanFactory;
	
	protected final Map<String, String> knowConverters = new HashMap<String, String>();
	
	protected final Map<String, String> knowFacades = new HashMap<String, String>();
	
	
	//Classe de Log
    protected transient Log log = getLog();
    @Transient
	protected Log getLog() {
        return LogFactory.getLog(this.getClass());
    }
	
    //converter
    public Converter getConverter(Class bean) {
    	if(bean == null){
			return null;
		}
    	return (Converter)getService(bean.getName(), true, knowConverters);
    }
    public Converter getConverter(String className) {
    	return (Converter)getService(className, true, knowConverters);
    }
    public Converter getConverter(String className, boolean longException) {
    	return (Converter)getService(className, longException, knowConverters);
    }
    
    //facade
    public FacadeContract getFacade(Class bean) {
    	if(bean == null){
			return null;
		}
    	return (FacadeContract)getService(bean.getName(), true, knowFacades);
    }
    public FacadeContract getFacade(String className) {
    	return (FacadeContract)getService(className, true, knowFacades);
    }
    public FacadeContract getFacade(String className, boolean longException) {
    	return (FacadeContract)getService(className, longException, knowFacades);
    }
    
	Object getService(String className, boolean longException, Map<String, String> map) {
		if(className == null){
			return null;
		}
		String serviceBeanName = null;
		Object retorno = null;
		try{
			serviceBeanName = map.get(className);
			retorno = beanFactory.getBean(serviceBeanName);
			return retorno;
		}
		catch(Exception exp){
			if(longException && getLog().isErrorEnabled()){
				getLog().error("getService : Error trying to get the service for bean: " + className, exp);
			}
			throw new ISWEConfigurationException("basicservicelocator.getservice", exp, 
					"Bean Class: " + className,
					"Bean Factory: " + beanFactory.toString());
		}
	}

	public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
		this.beanFactory = beanFactory;
	}

	public Map<String, String> getKnowConverters() {
		return knowConverters;
	}
	
	public String toString() {
		return "ServiceClass: " + this.getClass().getName() + " knowConverters: " + knowConverters.toString();
	}
}
